import java.io.BufferedReader;
import java.io.FileReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Automata {
	private boolean finiteState[];
	private char stateTrans[][];
	private int currentState;

	private Automata(int stateCount, char stTrans[], int finStates[]) {
		finiteState = new boolean[stateCount + 1];
		stateTrans = new char[stateCount + 1][255];

		for (int i = 0; i < stTrans.length; i += 3) {
			stateTrans[Integer.parseInt(String.valueOf(stTrans[i]))][stTrans[i + 1]] = (char) Integer
					.parseInt(String.valueOf(stTrans[i + 2]));
		}

		for (int i = 0; i < finStates.length; i++) {
			finiteState[finStates[i]] = true;
		}
	}

	public boolean process(String input) {
		currentState = 1;
		for (char c : input.toCharArray()) {
			currentState = stateTrans[currentState][c];
		}

		return finiteState[currentState];
	}

	public static Automata createAutomata(String automataDefFile) {
		try {
			BufferedReader reader = new BufferedReader(new FileReader(
					automataDefFile));

			String automataDef = "";
			String line = "";

			while (null != (line = reader.readLine())) {
				automataDef += line;
			}

			reader.close();

			automataDef = automataDef.replaceAll("\\s*", "");
			String states = "states\\([0-9][0-9]*\\)";
			String trans = "trans=\\{(\\([0-9][0-9]*,.,[0-9][0-9]*\\),)*\\([0-9][0-9]*,.,[0-9][0-9]*\\)\\}";
			String finite = "finite=\\{([0-9][0-9]*,)*[0-9][0-9]*\\}";
			String defRegExp = states + trans + finite;

			if (automataDef.matches(defRegExp)) {
				Pattern pt = Pattern.compile(states);
				Matcher mt = pt.matcher(automataDef);
				mt.find();
				String found = mt.group();
				int stateCount = Integer.parseInt(found.substring(7,
						found.length() - 1));

				pt = Pattern.compile(trans);
				mt = pt.matcher(automataDef);
				mt.find();
				found = mt.group();
				char transitions[] = found.substring(7, found.length() - 1)
						.replaceAll("[\\(\\),]", "").toCharArray();

				pt = Pattern.compile(finite);
				mt = pt.matcher(automataDef);
				mt.find();
				found = mt.group();

				String finSt[] = found.substring(8, found.length() - 1).split(
						",");
				int finiteStates[] = new int[finSt.length];

				for (int i = 0; i < finiteStates.length; i++) {
					finiteStates[i] = Integer.parseInt(finSt[i]);
				}

				return new Automata(stateCount, transitions, finiteStates);
			} else {
				System.err.println("Syntax error!");
			}

		} catch (Exception e) {
			System.err.println(e.getMessage());
		}

		return null;
	}
}
